package com.keya.selector;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.keya.base.exception.BusinessException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Slf4j
public class SelectorResolver<T> {


    public static <T> QueryWrapper<T> getQueryWrapper(QueryWrapper<T> queryWrapper, String selector, Map<String, String> mapperMap) throws Exception {
        if (mapperMap.size() == 0) return queryWrapper;
        if (StringUtils.isEmpty(selector)) return queryWrapper;
        ObjectMapper mapper = new ObjectMapper();
        ObjectNode node = (ObjectNode) mapper.readTree(selector);
        Iterator<String> iterator = node.fieldNames();
        while (iterator.hasNext()) {
            String next = iterator.next();
            JsonNode jsonNode = node.get(next);
            String desc = jsonNode.asText();
            if (!next.startsWith("$")) {
                String column = mapperMap.get(next);
                if (StringUtils.isEmpty(column)) {
                    throw new BusinessException(-1, "存在未指定的字段");
                }
                if (StringUtils.isEmpty(desc)) {
                    Iterator<String> sonIterator = jsonNode.fieldNames();
                    while (sonIterator.hasNext()) {
                        String symbol = sonIterator.next();
                        JsonNode contentNode = jsonNode.get(symbol);
                        String content = contentNode.asText();
                        if (StringUtils.isNotEmpty(content)) {
                            switch (symbol) {
                                case "$gt":
                                    queryWrapper.gt(column, content);
                                    break;
                                case "$lt":
                                    queryWrapper.lt(column, content);
                                    break;
                                case "$gte":
                                    queryWrapper.ge(column, content);
                                    break;
                                case "$lte":
                                    queryWrapper.le(column, content);
                                    break;
                                case "$ne":
                                    queryWrapper.ne(column, content);
                                    break;
                                case "$isNotNull":
                                    queryWrapper.isNotNull(column);
                                    break;
                                case "$isNull":
                                    queryWrapper.isNull(column);
                                    break;
                            }
                        } else {
                            switch (symbol) {
                                case "$in":
                                    Iterator<JsonNode> jsonNodeIterator = contentNode.iterator();
                                    List<String> values = new ArrayList<>();
                                    while (jsonNodeIterator.hasNext()) {
                                        String ele = jsonNodeIterator.next().asText();
                                        values.add(ele);
                                    }
                                    if (values.size() > 0) {
                                        queryWrapper.in(column, values);
                                    }
                                    break;
                                case "$notIn":
                                    Iterator<JsonNode> jsonNodeIterator1 = contentNode.iterator();
                                    List<String> values1 = new ArrayList<>();
                                    while (jsonNodeIterator1.hasNext()) {
                                        String ele = jsonNodeIterator1.next().asText();
                                        values1.add(ele);
                                    }
                                    if (values1.size() > 0) {
                                        queryWrapper.notIn(column, values1);
                                    }
                                    break;
                            }
                        }
                    }
                } else {
                    Pattern pLike = Pattern.compile("\\/(.*)\\/");
                    Matcher matcher = pLike.matcher(desc);
                    if (matcher.find()) {
                        String group = matcher.group(1);
                        queryWrapper.like(column, group);
                    } else {
                        queryWrapper.eq(column, desc);
                    }
                }
            }
        }
        return queryWrapper;
    }

    public static <T> QueryWrapper<T> getQueryWrapper(String selector, Class clazz) throws Exception {
        Map<String, String> stringStringMap = ConditionRegistry.CONDITION_MAP.get(clazz);
        return getQueryWrapper(selector, stringStringMap);
    }

    public static <T> QueryWrapper<T> getQueryWrapper(String selector, Map<String, String> mapperMap) throws Exception {
        QueryWrapper<T> queryWrapper = new QueryWrapper<T>();
        return getQueryWrapper(queryWrapper, selector, mapperMap);
    }


}
